<?php 

function treePath(array &$dataset, $campoIdentificador, $campoIdentificadorPadre, $campoTexto,$separacion_rutas=' > ', array $ids=array(),$full=false){
    $tree=buildObjectTree($dataset,$campoIdentificador,$campoIdentificadorPadre);
    
    
    
    if(!function_exists('rutas')){
        function rutas(&$tree,&$campoIdentificador,&$campoTexto,&$separacion_rutas,&$ids,$ruta=array(),$full){
            static $rutas=array();
            static $i=0;
                        
            foreach ($tree as $value){
            	
                //se copia la ruta padre para pasarsela a los hijos          	
            	$rutas[$i]=$ruta;

                //se añade el nuevo segmento
                if(!empty($rutas[$i][$campoTexto])){
                    $rutas[$i][$campoTexto].=$separacion_rutas.$value->$campoTexto;
                } else {
                    $rutas[$i][$campoTexto]=$value->$campoTexto;
                }
                

                // Se añaden todos los datos al nuevo segmento
                $rutas[$i][$campoIdentificador]=$value->$campoIdentificador;
                $rutas[$i]['names'][]    = $value->$campoTexto;
                $rutas[$i]['ids'][]        = $value->$campoIdentificador;
                
                
                foreach ($value as $key=>$dato){
                	if($key!='children' && $key!=$campoIdentificador && $key!=$campoTexto){
                		if(!isset($rutas[$i][$key])){
	                		$rutas[$i][$key]=array();
                		}
	                	$rutas[$i][$key][count($rutas[$i][$key])]=$dato;
                	}
                }
                
                //si tiene hijos y no se ha encontrado uno de los ids buscados se llama a la funcion
                // si no, se incrementa el contador para pasar a una nueva ruta si existiera
                if(!empty($value->children) && (!in_array($value->$campoIdentificador, $ids) || $full)){
                    rutas($value->children,$campoIdentificador,$campoTexto,$separacion_rutas,$ids,$rutas[$i++],$full);
                }else{
                    ++$i;
                }
            }
            return $rutas;
        }
    }

    //llamada a la funcion
    $list=rutas($tree,$campoIdentificador,$campoTexto,$separacion_rutas,$ids,array(),$full);
    
    //si hay ids dados
    $num_ids=count($ids);
    if($num_ids){
        //se recuperan solo las rutas que contengan los ids dados
        foreach ($list as $key=>$ruta){              
            if(!array_intersect($ids,$ruta['ids'])){
                unset($list[$key]);
            }
        }
        //Se renumeran los indices de las rutas
        $list=array_values($list);
    }

    return $list;
}


function buildArrayTree(array &$dataset, $campoIdentificador, $campoIdentificadorPadre) {
    $tree = array();
 
    /* Most datasets in the wild are enumerative arrays and we need associative array
       where the same ID used for addressing parents is used. We make associative
       array on the fly */
    $references = array();
    foreach ($dataset as $id => &$node) {
        // Add the node to our associative array using it's ID as key
        $references[$node[$campoIdentificador]] = &$node;
 
        // Add empty placeholder for children
        $node['children'] = array();
 
        // It it's a root node, we add it directly to the tree
        if (is_null($node[$campoIdentificadorPadre]) || !$node[$campoIdentificadorPadre]) {
            $tree[$node[$campoIdentificador]] = &$node;
        } else {
            // It was not a root node, add this node as a reference in the parent.
            $references[$node[$campoIdentificadorPadre]]['children'][$node[$campoIdentificador]] = &$node;
        }
    }
 
    return $tree;
}

function buildObjectTree(array &$dataset, $campoIdentificador, $campoIdentificadorPadre) {
    $tree = array();
 
    /* Most datasets in the wild are enumerative arrays and we need associative array
       where the same ID used for addressing parents is used. We make associative
       array on the fly */
    $references = array();
    foreach ($dataset as $id => &$node) {
        // Add the node to our associative array using it's ID as key
        if(!isset($references[$node->$campoIdentificador])){
        	$references[$node->$campoIdentificador]= new stdClass();
        }
        $references[$node->$campoIdentificador]=(object) array_merge((array)$references[$node->$campoIdentificador], (array)$node);
        /*foreach ($node as $key=>$value){
        	$references[$node->$campoIdentificador]->$key=$value;
        }*/
        // It it's a root node, we add it directly to the tree
        if (is_null($node->$campoIdentificadorPadre) || !$node->$campoIdentificadorPadre) {
            $tree[$node->$campoIdentificador] = &$references[$node->$campoIdentificador];
        } else {
            // It was not a root node, add this node as a reference in the parent.
            $references[$node->$campoIdentificadorPadre]->children[$node->$campoIdentificador] = &$references[$node->$campoIdentificador];
        }
        //print_r($references);
    }
    return $tree;
}


function buildHtmlTree(array &$tree, $id, $texto,$baseClass,$enlace=false){
    static $level=0;
?>
    <ul class="<?php echo $baseClass; ?>" level="<?php echo $level; ?>">
    <?php foreach($tree as $elemento): 
        $tipo='final';
        $parent=false;
        if(!empty($elemento->children)){
            $tipo='parent';
            $parent=true;
        }
        ?>
        <li idTree="<?php echo $elemento->$id; ?>" class="<?php echo $baseClass; ?>_item <?php echo $tipo; ?>" level="<?php echo $level; ?>">
        
	        <div class="<?php echo $baseClass;?>_item_row">
		        <span class="<?php echo $baseClass; ?>_item_icon <?php echo $tipo; ?>"></span>
		        <div class="tree_item_content">
		            <?php 
		            if($enlace){
		                echo anchor($elemento->enlace, $elemento->$texto);
		            } else {
		                echo $elemento->$texto;
		            }
		            ?>
		        </div>
	        </div>
        <?php 
            if($parent){
                ++$level;
                buildHtmlTree($elemento->children,$id,$texto,$baseClass,$enlace);
                $level=0;
            } 
        ?>
        </li>
    <?php endforeach; ?>
    </ul>
<?php 
}